'''
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http:#www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
'''
from base.rdf.ModelCon import ModelCon
from base.rdf.RDFReaderF import RDFReaderF
from base.rdf.RDFWriterF import RDFWriterF
from base.shared.PrefixMapping import PrefixMapping

#import java.io.*;
#import java.util.*;
#import java.util.function.Supplier;

#import org.apache.jena.datatypes.*;
#import org.apache.jena.shared.*;

'''
 * An RDF Model.
 * <p>
 * An RDF model is a set of Statements.  Methods are provided for creating
 * resources, properties and literals and the Statements which link them,
 * for adding statements to and removing them from a model, for
 * querying a model and set operations for combining models.
 * <p>
 * Models may create Resources [URI nodes and bnodes]. Creating a Resource does
 * <i>not</i> make the Resource visible to the model Resources are only "in" Models
 * if Statements about them are added to the Model. Similarly the only way to "remove"
 * a Resource from a Model is to remove all the Statements that mention it.
 * <p>
 * When a Resource or Literal is created by a Model, the Model is free to re-use an
 * existing Resource or Literal object with the correct values, or it may create a fresh
 * one. [All Jena RDFNodes and Statements are immutable, so this is generally safe.]
 * <p>
 * This interface defines a set of primitive methods.  A set of
 * convenience methods which extends this interface, e.g. performing
 * automatic type conversions and support for enhanced resources,
 * is defined in:@link ModelCon.</p>
 *
 * <h2>System Properties</h2>
 *
 *
 * <h3>Firewalls and Proxies</h3>
 * <p>
 * Some of the methods, e.g. the read methods, may have to traverse a
 * firewall.  This can be accomplished using the standard java method
 * of setting system properties.  To use a socks proxy, include on the
 * java command line:</p>
 * <blockquote>
 * -DsocksProxyHost=[your-proxy-domain-name-or-ip-address]
 * </blockquote>
 *
 * <p>To use an http proxy, include on the command line:</p>
 * <blockquote>
 * -DproxySet=true -DproxyHost=[your-proxy] -DproxyPort=[your-proxy-port-number]
 * </blockquote>
 *
 * <p>Alternatively, these properties can be set programmatically, e.g.</p>
 *
 * <pre>
 *   System.getProperties().put("proxySet","true")
 *   System.getProperties().put("proxyHost","proxy.hostname")
 *   System.getProperties().put("proxyPort",port_number)
 * </pre>
'''
from abc import ABC, abstractmethod

# extends Lock  ModelGraphInterface
class Model(ModelCon, RDFReaderF, RDFWriterF, PrefixMapping):
    '''
     * @deprecated
    '''
    #@Override
    #@Deprecated
    # param 
    # result RDFReaderI
    @abstractmethod
    def getReader(self):
        pass

    '''
     * @deprecated
    '''
    #@Override
    #@Deprecated
    # param String lang
    # result RDFReaderI
    @abstractmethod
    def getReader(self, lang):
        pass

    '''
     * @deprecated
    '''
    #@Override
    #@Deprecated
    # param 
    # result RDFWriterI
    @abstractmethod
    def getWriter(self):
        pass

    '''
     * @deprecated
    '''
    #@Override
    #@Deprecated
    # param String lang
    # result RDFWriterI
    @abstractmethod
    def getWriter(self, lang):
        pass

    '''
     * size will return the number of statements in a concrete model,
     * for a virtualized model such as one created by an inference engine,
     * it will return an estimated lower bound for the number of statements
     * in the model but it is possible for a subsequent listStatements on
     * such a model to discover more statements than size() indicated.
     *
     * @return the number of statements in a concrete model or an estimated
     * lower bound on the number of statements in an virtualized model
    '''
    # param 
    # result long
    @abstractmethod
    def size(self):
        pass

    '''
     * Answer true iff the model contains no explicit statements (ie it's size is zero,
     * listStatements() would deliver the empty iterator).
     *
     * @return true iff the model contains no explicit statements.
    '''
    # param 
    # result boolean
    @abstractmethod
    def isEmpty(self):
        pass

    '''
     * List all resources which are subjects of statements.
     *
     * <p>Subsequent operations on those resource may modify this model.</p>
     *
     * @return an iterator over a set of resources which are subjects of statements
     * in the model. .remove() is not implemented on this iterator.
    '''
    # param 
    # result ResIterator
    @abstractmethod
    def listSubjects(self):
        pass

    '''
     * (You probably don't want this method more likely you want the
     * PrefixMapping methods that Model supports.) List the namespaces used
     * by predicates and types in the model. This method is really intended
     * for use by the RDF/XML writer, which needs to know these
     * namespaces to generate correct and vaguely pretty XML.
     * <p>
     * The namespaces returned are those of (a) every URI used as a property in the
     * model and (b) those of every URI that appears as the object of an rdf:type statement.
     * <p>
     * Note that the notion of "namespace" used here is not that of an XML
     * prefix-namespace, but just of the minimal legal left part of a URI
     * (see Util.splitNamespace for details). If you want the RDF/XML (or
     * N3) namespaces, treat the Model as a PrefixMapping.
     *
     * @return an iterator over every predicate and type namespace
     * @see org.apache.jena.shared.PrefixMapping
    '''
    # param 
    # result NsIterator
    @abstractmethod
    def listNameSpaces(self):
        pass

    '''
     * Return a Resource instance with the given URI in this model. <i>This method
     * behaves identically to <code>createResource(String)</code></i> and exists as
     * legacy: createResource is now capable of, and allowed to, reuse existing objects.
     * <p>
     * Subsequent operations on the returned object may modify this model.
     *
     * @param uri the URI of the resource
     * @return a resource instance
    '''
    # param String uri
    # result Resource
    @abstractmethod
    def getResource(self, uri):
        pass

    '''
     * Return a Property instance with the given URI in this model. <i>This method
     * behaves identically to <code>createProperty(String,String)</code></i> and exists as
     * legacy: createProperty is now capable of, and allowed to, reuse existing objects.
     * <p>
     * Subsequent operations on the returned property may modify this model.
     *
     * @param nameSpace the RDF namespace of the property
     * @param localName the localName of the property in its namespace
     * @return a property linked to this model
    '''
    # param String nameSpace, String localName
    # result Property
    # @abstractmethod
    # def getProperty(self, nameSpace, localName):
    #     pass

    '''
     * Create a new anonymous resource whose model is this model. This bnode will
     * have a new AnonId distinct from any allocated by any other call of this method.
     * <p>
     * Subsequent operations on the returned resource may modify this model.
     *
     * @return a new anonymous resource linked to this model.
    '''
    # param 
    # result Resource
    @abstractmethod
    def createResource(self):
        pass

    '''
     * Create a blank node resource with a specified identifier. The resulting bnode
     * will be equal to any other bnode with the same AnonId (even if they are in
     * separate models - be warned). The intended use for this method is to allow
     * bnode round-tripping between Jena models and other representations.
     * <p>
     * This method may return an existing bnode with the correct AnonId and model, or it
     * may construct a fresh one, as it sees fit.
     * <p>
     * Operations on the result may modify this model
     *
     * @param id the identifier to use for this blank node
     * @return a blank node with that identifier
    '''
    # param AnonId id
    # result Resource
    @abstractmethod
    def createResource(self, id):
        pass

    '''
     * Create a new resource associated with this model. If the uri string is null, this creates
     * a bnode, as per <code>createResource()</code>. Otherwise it creates a URI node.
     * A URI resource is .equals() to any other URI Resource with the same URI (even in
     * a different model - be warned).
     * <p>
     * This method may return an existing Resource with the correct URI and model, or it
     * may construct a fresh one, as it sees fit.
     * <p>
     * Operations on the result Resource may change this model.
     *
     * @param uri the URI of the resource to be created
     * @return a new resource linked to this model.
    '''
    # param String uri
    # result Resource
    @abstractmethod
    def createResource(self, uri):
        pass

    '''
     * Create a resource that represents a statement. This is in support of RDF-star.
     *
     * @param statement
     * @return a new resource linked to this model.
    '''
    # param Statement statement
    # result Resource
    @abstractmethod
    def createResource(self, statement):
        pass

    '''
     * Create a property with a given URI composed from a namespace part and a
     * localname part by concatenating the strings.
     * <p>
     * This method may return an existing property with the correct URI and model, or it
     * may construct a fresh one, as it sees fit.
     * <p>
     * Subsequent operations on the returned property may modify this model.
     *
     * @param nameSpace the nameSpace of the property
     * @param localName the name of the property within its namespace
     * @return a property instance
    '''
    # param String nameSpace, String localName
    # result Property
    @abstractmethod
    def createProperty(self, nameSpace, localName):
        pass

    '''
     * Create an untyped literal from a String value with a specified language.
     *
     * @param v        the lexical form of the literal
     * @param language the language associated with the literal
     * @return a new literal representing the value v with the given language
    '''

    # param String v, String language
    # result Literal
    @abstractmethod
    def createLiteral(self, v, language):
        pass

    '''
     * Create a literal from a String value. An existing literal
     * of the right value may be returned, or a fresh one created.
     * The use of the wellFormed flag is to create typed literals of
     * type rdf:XMLLiteral, without error checking. This should
     * only be use when the lexical form is known to already be
     * in exclusive canonical XML.
     *
     * @param v          the lexical form of the literal
     * @param wellFormed true if the Literal is well formed XML, in the lexical space of rdf:XMLLiteral
     * @return a new literal
     * @deprecated To be removed. Argument 'wellFormed' is ignored
    '''
    #@Deprecated
    # param String v, boolean wellFormed
    # result Literal
    # @abstractmethod
    # def createLiteral(self, v, wellFormed):
    #     pass

    '''
     * Build a typed literal from its lexical form. The
     * lexical form will be parsed now and the value stored. If
     * the form is not legal this will throw an exception.
     * <p>
     * Note that in preview releases of Jena2 it was also possible to specify
     * a language type. Changes to the RDF specification mean that this is no longer
     * legal except for plain literals. To create a plain literal with a language tag
     * use:@link #createLiteral(String, String) createLiteral.
     *
     * @param lex   the lexical form of the literal
     * @param dtype the type of the literal, null for old style "plain" literals
     * @throws DatatypeFormatException if lex is not a legal form of dtype
    '''
    # param String lex, RDFDatatype dtype
    # result Literal
    # @abstractmethod
    # def createTypedLiteral(self, lex, dtype):
    #     pass

    '''
     * Build a typed literal from its value form.
     * <p>
     * Note that in preview releases of Jena2 it was also possible to specify
     * a language type. Changes to the RDF specification mean that this is no longer
     * legal except for plain literals. To create a plain literal with a language tag
     * use:@link #createLiteral(String, String) createLiteral.
     * </p>
     *
     * @param value the value of the literal
     * @param dtype the type of the literal, null for old style "plain" literals
    '''
    # param Object value, RDFDatatype dtype
    # result Literal
    @abstractmethod
    def createTypedLiteral(self, value, dtype):
        pass

    '''
     * Build a typed literal label from its value form using
     * whatever datatype is currently registered as the the default
     * representation for this java class. No language tag is supplied.
     *
     * @param value the literal value to encapsulate
    '''
    #@Override
    # param Object value
    # result Literal
    @abstractmethod
    def createTypedLiteral(self, value):
        pass

    '''
     * Create a Statement instance. (Creating a statement does not add it to the set of
     * statements in the model see Model::add). This method may return an existing
     * Statement with the correct components and model, or it may construct a fresh one,
     * as it sees fit.
     * <p>
     * Subsequent operations on the statement or any of its parts may modify this model.
     *
     * @param s the subject of the statement
     * @param p the predicate of the statement
     * @param o the object of the statement
     * @return the new statement
    '''
    # param Resource s, Property p, RDFNode o
    # result Statement
    @abstractmethod
    def createStatement(self, s, p, o):
        pass

    '''
     * Answer a new empty list. This is equivalent to a list consisting only
     * of <code>rdf:nil</code>.
     *
     * @return An RDF-encoded list of no elements
    '''
    # param
    # result RDFList
    @abstractmethod
    def createList(self):
        pass

    '''
     * <p>Answer a new list containing the resources from the given iterator, in order.</p>
     *
     * @param members An iterator, each value of which is expected to be an RDFNode
     * @return An RDF-encoded list of the elements of the iterator
    '''
    # param Iterator<? extends RDFNode> members
    # result RDFList
    @abstractmethod
    def createList2(self, extends):
        pass


    '''
     * <p>Answer a new list containing the nodes from the given eleemnts, in order.
     * If the list of elements is empty, until the list is made the object or subject in the model, or has an element added,
     * it will not appear in the model (e.g. when written out).
     *
     * @param members An array of RDF nodes that will be the members of the list
     * @return An RDF-encoded list
    '''
    # param RDFNode... members
    # result RDFList
    # @abstractmethod
    # def createList(self, members):
    #     pass


    '''
     * Add a statement to this model.
     *
     * @param s The statement to be added.
     * @return This model.
    '''
    # param Statement s
    # result Model
    @abstractmethod
    def add(self, s):
        pass

    '''
     * Add all the statements to the Model, using through the bulk update interface.
     *
     * @param statements the array of statements to add
     * @return this model, to allow cascading
    '''
    # param Statement[] statements
    # result Model
    # @abstractmethod
    # def add(self, statements):
    #     pass

    '''
     * Remove all the statements from the Model, using the bulk update interface.
     *
     * @param statements the array of statements to be added
     * @return this model, to allow cascading
    '''
    # param Statement[] statements
    # result Model
    @abstractmethod
    def remove(self, statements):
        pass

    '''
     * add all the statements in the List to this Model, going through the bulk
     * update interface (which means turning them into triples in one form or
     * another).
     *
     * @param statements a List of Statements
     * @return this model, to allow cascading
    '''
    # param List<Statement> statements
    # result Model
    # @abstractmethod
    # def add(self, statements):
    #     pass

    '''
     * Remove all the statements in the list from this model, using the bulk
     * update interface.
     *
     * @param statements a List of Statements to remove
     * @return this model, to allow cascading
    '''
    # param List<Statement> statements
    # result Model
    # @abstractmethod
    # def remove(self, statements):
    #     pass

    '''
     * Add all the statements returned by an iterator to this model.
     *
     * @param ite An iterator which returns the statements to be added.
     * @return this model
    '''
    # param StmtIterator ite
    # result Model
    # @abstractmethod
    # def add(self, ite):
    #     pass

    '''
     * Add all the statements in another model to this model, including the
     * reified statements.
     *
     * @param m The model whose statements are to be added.
     * @return this model
    '''
    # param Model m
    # result Model
    # @abstractmethod
    # def add(self, m):
    #     pass

    '''
     * Add the RDF statements from a document.
     * Uses content negotiation to request appropriate mime types.
     * If the content type is not found, it may guess from the URL.
     * <p>See:@link Model for a description of how to traverse a firewall.</p>
     * <p>
     * See <a href="http:#jena.apache.org/documentation/io/index.html">"Reading and Writing RDF in Apache Jena"</a>
     * for more information about determining the syntax.
     * </p>
     *
     * @param url of the document containing the RDF statements.
     * @return this model
    '''
    # param String url
    # result Model
    @abstractmethod
    def read(self, url):
        pass

    '''
     * Add statements from a document.
     * This method assumes the concrete syntax is RDF/XML.
     * See:@link #read(InputStream, String, String) for explicitly setting the language.
     * <p>
     * See <a href="http:#jena.apache.org/documentation/io/index.html">"Reading and Writing RDF in Apache Jena"</a>
     * for more information about concrete syntaxes.
     * </p>
     *
     * @param in   the input stream
     * @param base the base uri to be used when converting relative
     *             URI's to absolute URI's. (Resolving relative URIs and fragment IDs is done
     *             by prepending the base URI to the relative URI/fragment.) If there are no
     *             relative URIs in the source, this argument may safely be <code>null</code>.
     *             If the base is the empty string, then relative URIs <i>will be retained in
     *             the model</i>. This is typically unwise and will usually generate errors
     *             when writing the model back out.
     * @return the current model
    '''
    # param InputStream in, String base
    # result Model
    # @abstractmethod
    # def read(self, input, base):
    #     pass

    '''
     * Add RDF statements represented in language <code>lang</code> to the model.
     * <br />Predefined values for <code>lang</code> are "RDF/XML", "N-TRIPLE",
     * "TURTLE" (or "TTL") and "N3".
     * <code>null</code> represents the default language, "RDF/XML".
     * "RDF/XML-ABBREV" is a synonym for "RDF/XML".
     * <br />
     *
     * @param base the base uri to be used when converting relative
     *             URI's to absolute URI's. (Resolving relative URIs and fragment IDs is done
     *             by prepending the base URI to the relative URI/fragment.) If there are no
     *             relative URIs in the source, this argument may safely be <code>null</code>.
     *             If the base is the empty string, then relative URIs <i>will be retained in
     *             the model</i>. This is typically unwise and will usually generate errors
     *             when writing the model back out.
     *             <p>
     *             See <a href="http:#jena.apache.org/documentation/io/index.html">"Reading and Writing RDF in Apache Jena"</a>
     *             for more information about concrete syntaxes.
     *             </p>
     * @param lang the language of the serialization <code>null</code>
     *             selects the default
     * @param in   the source of the input serialization
     * @return this model
    '''
    # param InputStream in, String base, String lang
    # result Model
    # @abstractmethod
    # def read(self, input, base, lang):
    #     pass

    '''
     * Using this method is often a mistake.
     * Add statements from an RDF/XML serialization.
     * It is generally better to use an InputStream if possible,
     * otherwise there is a danger of a
     * mismatch between the character encoding of say the FileReader and the
     * character encoding of the data in the file.
     * <p>
     * It is better to explicitly set the serialization format.
     * See:@link #read(InputStream, String, String) for explicitily setting the serialization language.
     *
     * <p>
     * See <a href="http:#jena.apache.org/documentation/io/index.html">"Reading and Writing RDF in Apache Jena"</a>
     * for more information about concrete syntaxes.
     * </p>
     *
     * @param reader
     * @param base   the base uri to be used when converting relative URI's to absolute URI's and to guess the RDF serialization syntax.
     * @return the current model
    '''
    # param Reader reader, String base
    # result Model
    # @abstractmethod
    # def read(self, reader, base):
    #     pass

    '''
     * Add statements from a serializion in language <code>lang</code> to the
     * model.
     * <br />Predefined values for <code>lang</code> are "RDF/XML", "N-TRIPLE",
     * "TURTLE" (or "TTL") and "N3".
     * <code>null</code> represents the default language, "RDF/XML".
     * "RDF/XML-ABBREV" is a synonym for "RDF/XML".
     * <br />
     *
     * <p>See:@link Model for a description of how to traverse a firewall.</p>
     * <p>
     * See <a href="http:#jena.apache.org/documentation/io/index.html">"Reading and Writing RDF in Apache Jena"</a>
     * for more information about concrete syntaxes.
     * </p>
     *
     * @param url  a string representation of the url to read from
     * @param lang the language of the serialization
     * @return this model
    '''
    # param String url, String lang
    # result Model
    # @abstractmethod
    # def read(self, url, lang):
    #     pass

    '''
     * Using this method is often a mistake.
     * Add RDF statements represented in language <code>lang</code> to the model.
     * <br />Predefined values for <code>lang</code> are "RDF/XML", "N-TRIPLE",
     * "TURTLE" (or "TTL") and "N3".
     * <code>null</code> represents the default language, "RDF/XML".
     * "RDF/XML-ABBREV" is a synonym for "RDF/XML".
     * <br />
     * It is generally better to use an InputStream if possible.
     *:@link Model#read(InputStream, String), otherwise there is a danger of a
     * mismatch between the character encoding of say the FileReader and the
     * character encoding of the data in the file.
     *
     * @param base   the base uri to be used when converting relative
     *               URI's to absolute URI's. (Resolving relative URIs and fragment IDs is done
     *               by prepending the base URI to the relative URI/fragment.) If there are no
     *               relative URIs in the source, this argument may safely be <code>null</code>.
     *               If the base is the empty string, then relative URIs <i>will be retained in
     *               the model</i>. This is typically unwise and will usually generate errors
     *               when writing the model back out.
     * @param lang   the language of the serialization <code>null</code>
     *               selects the default
     * @param reader the source of the input serialization
     * @return this model
    '''
    # param Reader reader, String base, String lang
    # result Model
    # @abstractmethod
    # def read(self, reader, base, lang):
    #     pass

    '''
     * Read into this model the RDF at <code>url</code>, using
     * <code>baseURI</code> as the base URI if it is non-null. The RDF is assumed
     * to be RDF/XML unless <code>lang</code> is non-null, in which case it names
     * the language to be used. Answer this model.
    '''
    # param String url, String base, String lang
    # result Model
    # @abstractmethod
    # def read(self, url, base, lang):
    #     pass

    # output operations

    '''
     * <p>Write the model as an XML document.
     * It is often better to use an OutputStream rather than a Writer, since this
     * will avoid character encoding errors.
     * </p>
     *
     * @param writer A writer to which the XML will be written
     * @return this model
    '''
    # param Writer writer
    # result Model
    # @abstractmethod
    # def write(self, writer):
    #     pass

    '''
     * <p>Write a serialized representation of a model in a specified language.
     * It is often better to use an OutputStream rather than a Writer, since this
     * will avoid character encoding errors.
     * </p>
     * <p>The language in which to write the model is specified by the
     * <code>lang</code> argument.  Predefined values are "RDF/XML",
     * "RDF/XML-ABBREV", "N-TRIPLE", "TURTLE", (and "TTL") and "N3".  The default value,
     * represented by <code>null</code> is "RDF/XML".</p>
     *
     * @param writer The output writer
     * @param lang   The output language
     * @return this model
    '''
    # param Writer writer, String lang
    # result Model
    # @abstractmethod
    # def write(self, writer, lang):
    #     pass

    '''
     * <p>Write a serialized representation of a model in a specified language.
     * It is often better to use an OutputStream rather than a Writer,
     * since this will avoid character encoding errors.
     * </p>
     * <p>The language in which to write the model is specified by the
     * <code>lang</code> argument.  Predefined values are "RDF/XML",
     * "RDF/XML-ABBREV", "N-TRIPLE", "TURTLE", (and "TTL") and "N3".  The default value,
     * represented by <code>null</code>, is "RDF/XML".</p>
     *
     * @param writer The output writer
     * @param base   The base uri for relative URI calculations.
     *               <code>null</code> means use only absolute URI's.
     * @param lang   The language in which the RDF should be written
     * @return this model
    '''
    # param Writer writer, String lang, String base
    # result Model
    @abstractmethod
    def write(self, writer, lang, base):
        pass


    '''
     * <p>Write a serialization of this model as an XML document.
     * </p>
     * <p>The language in which to write the model is specified by the
     * <code>lang</code> argument.  Predefined values are "RDF/XML",
     * "RDF/XML-ABBREV", "N-TRIPLE" and "N3".  The default value is
     * represented by <code>null</code> is "RDF/XML".</p>
     *
     * @param out The output stream to which the XML will be written
     * @return This model
    '''
    # param OutputStream out
    # result Model
    # @abstractmethod
    # def write(self, out):
    #     pass

    '''
     * <p>Write a serialized representation of this model in a specified language.
     * </p>
     * <p>The language in which to write the model is specified by the
     * <code>lang</code> argument.  Predefined values are "RDF/XML",
     * "RDF/XML-ABBREV", "N-TRIPLE", "TURTLE", (and "TTL") and "N3".  The default value,
     * represented by <code>null</code>, is "RDF/XML".</p>
     *
     * @param out  The output stream to which the RDF is written
     * @param lang The output language
     * @return This model
    '''
    # param OutputStream out, String lang
    # result Model
    # @abstractmethod
    # def write(self, out, lang):
    #     pass

    '''
     * <p>Write a serialized representation of a model in a specified language.
     * </p>
     * <p>The language in which to write the model is specified by the
     * <code>lang</code> argument.  Predefined values are "RDF/XML",
     * "RDF/XML-ABBREV", "N-TRIPLE", "TURTLE", (and "TTL") and "N3".  The default value,
     * represented by <code>null</code>, is "RDF/XML".</p>
     *
     * @param out  The output stream to which the RDF is written
     * @param base The base uri to use when writing relative URI's. <code>null</code>
     *             means use only absolute URI's. This is used for relative
     *             URIs that would be resolved against the document retrieval URL.
     *             For some values of <code>lang</code>, this value may be included in the output.
     * @param lang The language in which the RDF should be written
     * @return This model
    '''
    # param OutputStream out, String lang, String base
    # result Model
    # @abstractmethod
    # def write(self, out, lang, base):
    #     pass

    '''
     * Removes a statement.
     *
     * <p> The statement with the same subject, predicate and object as
     * that supplied will be removed from the model.</p>
     *
     * @param s The statement to be removed.
     * @return this model
    '''
    # param Statement s
    # result Model
    # @abstractmethod
    # def remove(self, s):
    #     pass

    '''
     * Return a statement with given subject and property.
     * <p>If more than one statement witht the given subject and property
     * exists in the model, it is undefined which will be returned. If none
     * exist, an exception is thrown.
     *
     * @param s The subject of the statement to be returned.
     * @param p The property of the statement to be returned.
     * @return A statement from the model with the given subject and property.
     * @throws PropertyNotFoundException
    '''
    # param Resource s, Property p
    # result Statement
    # @abstractmethod
    # def getRequiredProperty(self, s, p):
    #     pass

    '''
     * Return a statement with given subject and property.
     * <p>If more than one statement witht the given subject and property
     * exists in the model, it is undefined which will be returned. If none
     * exist, an exception is thrown.
     *
     * @param s    The subject of the statement to be returned.
     * @param p    The property of the statement to be returned.
     * @param lang The language
     * @return A statement from the model with the given subject and property.
     * @throws PropertyNotFoundException
    '''
    # param Resource s, Property p, String lang
    # result Statement
    @abstractmethod
    def getRequiredProperty(self, s, p, lang):
        pass

    '''
     * Answer a statement (s, p, ?O) from this model. If none exist, return null
     * if several exist, pick one arbitrarily.
     *
     * @param s the subject of the statement to return
     * @param p the predicate of the statement to return
     * @return some statement (s, p, ?O) or null if none can be found
    '''
    # param Resource s, Property p
    # result Statement
    # @abstractmethod
    # def getProperty(self, s, p):
    #     pass

    '''
     * Answer a statement (s, p, ?O) from this model. If none exist, return null
     * if several exist, pick one arbitrarily.
     *
     * @param s    the subject of the statement to return
     * @param p    the predicate of the statement to return
     * @param lang language of the object
     * @return some statement (s, p, ?O@lang) or null if none can be found
    '''
    # param Resource s, Property p, String lang
    # result Statement
    @abstractmethod
    def getProperty(self, s, p, lang):
        pass

    '''
     * An alias for <code>listResourcesWithProperty(Property)</code>,
     * retained for backward compatibility. It may be deprecated in later
     * releases.
    '''
    # param Property p
    # result ResIterator
    @abstractmethod
    def listSubjectsWithProperty(self, p):
        pass

    '''
     * Answer an iterator [with no duplicates] over all the resources in this
     * model that have property <code>p</code>. <code>remove()</code>
     * is not implemented on this iterator.
    '''
    # param Property p
    # result ResIterator
    @abstractmethod
    def listResourcesWithProperty(self, p):
        pass

    '''
     * An alias for <code>listResourcesWithProperty</code>, retained for
     * backward compatibility. It may be deprecated in later releases.
    '''
    # param Property p, RDFNode o
    # result ResIterator
    # @abstractmethod
    # def listSubjectsWithProperty(self, p, o):
    #     pass

    '''
     * Answer an iterator [with no duplicates] over all the resources in this
     * model that have property <code>p</code> with value <code>o</code>.
     * <code>remove()</code> is not implemented on this iterator.
    '''
    # param Property p, RDFNode o
    # result ResIterator
    # @abstractmethod
    # def listResourcesWithProperty(self, p, o):
    #     pass

    '''
     * List all objects in a model.
     *
     * @return an iterator over the objects.  .remove() is not implemented on this iterator.
    '''
    # param 
    # result NodeIterator
    @abstractmethod
    def listObjects(self):
        pass

    '''
     * List all objects of a given property.  .remove() is not implemented on this iterator.
     *
     * @param p The predicate sought
     * @return an iterator over the objects
    '''
    # param Property p
    # result NodeIterator
    @abstractmethod
    def listObjectsOfProperty(self, p):
        pass

    '''
     * List the values of a property of a resource.
     *
     * @param p The predicate sought
     * @return an iterator over the objects.  .remove() is not implemented on this iterator.
    '''
    # param Resource s, Property p
    # result NodeIterator
    # @abstractmethod
    # def listObjectsOfProperty(self, s, p):
    #     pass

    '''
     * Determine whether this model contains any statements with a given subject
     * and property.
     *
     * @param s The subject sought (null for any).
     * @param p The predicate sought (null for any).
     * @return true if there exists within this model a statement with
     * subject s and property p, false otherwise
    '''
    # param Resource s, Property p
    # result boolean
    # @abstractmethod
    # def contains(self, s, p):
    #     pass

    '''
     * determine if the RDFNode r appears in any statement of this model.
     * (containsRDFNode is a horrible name, and in any case, even literals
     * will be resources one day)
     *
     * @param r the RDFNode to be searched for
     * @return true iff r appears as some subject, predicate, or object
    '''
    # param RDFNode r
    # result boolean
    @abstractmethod
    def containsResource(self, r):
        pass

    '''
     * Determine if an (S, P, O) pattern is present in this model, with null allowed
     * to represent a wildcard match.
     *
     * @param s The subject of the statement tested (null as wildcard).
     * @param p The predicate of the statement tested (null as wildcard).
     * @param o The object of the statement tested (null as wildcard).
     * @return true if the statement with subject s, property p and object o
     * is in the model, false otherwise
    '''
    # param Resource s, Property p, RDFNode o
    # result boolean
    @abstractmethod
    def contains(self, s, p, o):
        pass

    '''
     * Determine if a statement is present in this model.
     *
     * @param s The statement tested.
     * @return true if the statement s is in this model, false otherwise
    '''
    # param Statement s
    # result boolean
    # @abstractmethod
    # def contains(self, s):
    #     pass

    '''
     * Determine if any of the statements returned by an iterator are
     * contained in this model.
     *
     * @param ite an iterator of the statements to be tested
     * @return true if any of the statements returns by ite are contained
     * in this model and false otherwise.
    '''
    # param StmtIterator ite
    # result boolean
    @abstractmethod
    def containsAny(self, ite):
        pass

    '''
     * Determine if all of the statements returned by an iterator are
     * contained in this model.
     *
     * @param ite an iterator of the statements to be tested
     * @return true if any of the statements returns by ite are contained
     * in this model and false otherwise.
    '''
    # param StmtIterator ite
    # result boolean
    @abstractmethod
    def containsAll(self, ite):
        pass

    '''
     * Determine if any of the statements in a model are also contained
     * in this model.
     *
     * @param model the model containing the statements to be tested
     * @return true if any of the statements in model are also contained
     * in this model and false otherwise.
    '''
    # param Model model
    # result boolean
    # @abstractmethod
    # def containsAny(self, model):
    #     pass

    '''
     * Determine if all of the statements in a model are also contained
     * in this model.
     *
     * @param model the model containing the statements to be tested
     * @return true if all of the statements in model are also contained
     * in this model and false otherwise.
    '''
    # param Model model
    # result boolean
    # @abstractmethod
    # def containsAll(self, model):
    #     pass

    '''
     * Determine if this Statement has been reified in this Model.
     *
     * @param s The statement tested.
     * @return true iff a ReifiedStatement(s) has been created in this model
    '''
    # param Statement s
    # result boolean
    # @abstractmethod
    # def isReified(self, s):
    #     pass

    '''
     * Find or create a:@link ReifiedStatement corresponding to a Statement.
     *
     * @param s Statement which may or may not already be reified
     * @return a Resource [ReifiedStatement] that reifies the specified Statement.
    '''
    # param Statement s
    # result Resource
    # @abstractmethod
    # def getAnyReifiedStatement(self, s):
    #     pass

    '''
     * Remove all reifications (ie implicit reification quads) of _s_.
    '''
    # param Statement s
    # result void
    # @abstractmethod
    # def removeAllReifications(self, s):
    #     pass

    '''
     * Remove a particular reificiation.
    '''
    # param ReifiedStatement rs
    # result void
    # @abstractmethod
    # def removeReification(self, rs):
    #     pass

    '''
     * List all statements.
     *
     * <p>Subsequent operations on those statements may modify this model.</p>
     *
     * @return an iterator over all statements in the model.
    '''
    # param 
    # result StmtIterator
    @abstractmethod
    def listStatements(self):
        pass

    '''
     * List the statements matching a selector.
     *
     * <p>A statement is considered to match if the <CODE>test</CODE> method
     * of s returns true when called on s.</p>
     *
     * @param s A selector object.
     *          .
     * @return an iterator over the matching statements
    '''
    # param Selector s
    # result StmtIterator
    # @abstractmethod
    # def listStatements(self, s):
    #     pass

    '''
     * Find all the statements matching a pattern.
     * <p>Return an iterator over all the statements in a model
     * that match a pattern.  The statements selected are those
     * whose subject matches the <code>subject</code> argument,
     * whose predicate matches the <code>predicate</code> argument
     * and whose object matches the <code>object</code> argument.
     * If an argument is <code>null</code> it matches anything.</p>
     *
     * @param s The subject sought
     * @param p The predicate sought
     * @param o The value sought
     * @return an iterator over the subjects
    '''

    # param Resource s, Property p, RDFNode o
    # result StmtIterator
    # @abstractmethod
    # def listStatements(self, s, p, o):
    #     pass

    '''
     * Answer a ReifiedStatement that encodes _s_ and belongs to this Model.
     * <br>
     * result.getModel() == this
     * <br>
     * result.getStatement() .equals ( s )
    '''
    # param Statement s
    # result ReifiedStatement
    # @abstractmethod
    # def createReifiedStatement(self, s):
    #     pass

    '''
     * answer a ReifiedStatement that encodes _s_, belongs to this Model,
     * and is a Resource with that _uri_.
    '''
    # param String uri, Statement s
    # result ReifiedStatement
    # @abstractmethod
    # def createReifiedStatement(self, uri, s):
    #     pass

    '''
     * answer an iterator delivering all the reified statements "in" this model
    '''
    # param 
    # result RSIterator
    # @abstractmethod
    # def listReifiedStatements(self):
    #     pass

    '''
     * answer an iterator delivering all the reified statements "in" this model
     * that match the statement _st_.
    '''
    # param Statement st
    # result RSIterator
    # @abstractmethod
    # def listReifiedStatements(self, st):
    #     pass

    '''
     * Create a new model containing the statements matching a query.
     *
     * <p>A statement is considered to match if the <CODE>test</CODE> method
     * of s returns true when called on s.</p>
     *
     * @param s A selector object.
     *          .
     * @return an iterator over the matching statements
    '''
    # param Selector s
    # result Model
    @abstractmethod
    def query(self, s):
        pass

    '''
     * Create a new, independant, model containing all the statements in this model
     * together with all of those in another given model. By <i>independant</i>
     * we mean that changes to the result model do not affect the operand
     * models, and <i>vice versa</i>.
     * <p>
     * The new model need not be of the same type as either this model or
     * the argument model: typically it will be a memory-based model, even
     * if this model is a database model.
     *
     * @param model The other model whose statements are to be included.
     * @return A new model containing all the statements that are in either model
    '''
    # param Model model
    # result Model
    @abstractmethod
    def union(self, model):
        pass

    '''
     * Create a new, independant, model containing all the statements which are in both
     * this model and another.  As models are sets of statements, a statement
     * contained in both models will only appear once in the resulting model.
     * The new model need not be of the same type as either this model or
     * the argument model: typically it will be a memory-based model.
     *
     * @param model The other model.
     * @return A new model containing all the statements that are in both models.
    '''
    # param Model model
    # result Model
    @abstractmethod
    def intersection(self, model):
        pass

    '''
     * Create a new, independant, model containing all the statements in this model which
     * are not in another.
     * The new model need not be of the same type as either this model or
     * the argument model: typically it will be a memory-based model.
     *
     * @param model the other model whose statements are to be excluded.
     * @return a new model containing all the statements in this model that
     * are not in the given model.
    '''
    # param Model model
    # result Model
    @abstractmethod
    def difference(self, model):
        pass

    '''
     * Test whether the given object <code>m</code>
     * is a model that is equal to this model,
     * which is true iff the underlying graphs are identical Java
     * objects. This is not the same test as comparing whether two models
     * have the same structure (i.e. contain the same set of statements).
     * To test for strucutural equivalence, see:@link #isIsomorphicWith.
     *
     * @param m the model to be compared
     * @return true if <code>m</code> shares a graph object with this model
     * @see #isIsomorphicWith(Model)
    '''
    #@Override
    # param Object m
    # result boolean
    @abstractmethod
    def equals(self, m):
        pass

    '''
     * Begin a new transaction.
     *
     * <p> All changes made to a model within a transaction, will either
     * be made, or none of them will be made.</p>
     *
     * @return this model to enable cascading.
    '''
    # param 
    # result Model
    # @abstractmethod
    # def begin(self):
    #     pass

    '''
     * Abort the current transaction and abandon any changes in progress.
     *
     * @return this model to enable cascading.
    '''
    # param 
    # result Model
    # @abstractmethod
    # def abort(self):
    #     pass

    '''
     * Commit the current transaction.
     *
     * @return this model to enable cascading.
    '''
    # param 
    # result Model
    # @abstractmethod
    # def commit(self):
    #     pass

    '''
     * Execute the runnable <code>action</code> within a transaction. If it completes normally,
     * commit the transaction, otherwise abort the transaction.
    '''
    # param Runnable action
    # result void
    # @abstractmethod
    # def executeInTxn(self, action):
    #     pass

    '''
     * Execute the supplier <code>action</code> within a transaction. If it completes normally,
     * commit the transaction and return the result, otherwise abort the transaction.
    '''
    # <T> T calculateInTxn(Supplier<T> action)

    '''
     * Determine whether this model is independent.
     *
     * <p>For efficiency reasons, some implementations may create models which
     * which are dependent on others, i.e. a change in one model may cause
     * a change in another.  If this is the case this method will return false,
     * otherwise it will return true.</p>
     *
     * @return true if this model is indepdent of others
    '''
    # param 
    # result boolean
    @abstractmethod
    def independent(self):
        pass

    '''
     * Determine whether this model supports transactions.
     *
     * @return true if this model supports transactions.
    '''
    # param 
    # result boolean
    # @abstractmethod
    # def supportsTransactions(self):
    #     pass

    '''
     * Determine whether this model supports set operations.
     *
     * @return true if this model supports set operations.
    '''
    # param 
    # result boolean
    # @abstractmethod
    # def supportsSetOperations(self):
    #     pass

    '''
     * Compare this Model with another for equality ignoring the labels on
     * bNodes.
     * See
     * <a href="http:#www.w3.org/TR/rdf-concepts#section-Graph-syntax">RDF
     * Concepts</a>.
     * <p>Two models are isomorphic when each statement in one can be matched
     * with a statement in the other.  Statements which are identical match.</p>
     *
     * <p>Special treatment is given to anonymous nodes.  A binding is a one to
     * one mapping which maps each anonymous node in <code>this</code> model to
     * an anonymous node in <code>model</code>.  Two statements s1 and s2 match
     * under a binding if s1.subject is anonymous and s2.subject is anonymous
     * and the binding maps s1.subject to s2.subject.</p>
     *
     * <p>Two models are isomorphic if there is a binding that allows all the
     * statements in one model to match a a statement in the other.</p>
     *
     * @param g Compare against this.
     * @return boolean True if the two RDF graphs are isomorphic.
    '''
    # param Model g
    # result boolean
    @abstractmethod
    def isIsomorphicWith(self, g):
        pass

    '''
     * Close the Model and free up resources held.
     *
     * <p>Not all implementations of Model require this method to be called.  But
     * some do, so in general its best to call it when done with the object,
     * rather than leave it to the finalizer.</p>
    '''
    # param 
    # result void
    @abstractmethod
    def close(self):
        pass

    '''
     * Get the model lock for this model.
     * See also the convenience operations enterCriticalSection and leaveCriticalSection.
     *
     * @return The ModelLock object associated with this model
     * @see Lock
    '''
    # param 
    # result Lock
    # @abstractmethod
    # def getLock(self):
    #     pass

    '''
     * Register a listener for model-changed events on this model. The methods on
     * the listener will be called when API add/remove calls on the model succeed
     * [in whole or in part].
     * <p>
     * The same listener may be registered many times if so, it's methods will
     * be called as many times as it's registered for each event.
     *
     * @return this model, for cascading
     * @see ModelChangedListener
    '''
    # param ModelChangedListener listener
    # result Model
    # @abstractmethod
    # def register(self, listener):
    #     pass

    '''
     * Unregister a listener from model-changed events on this model. The
     * listener is dtached from the model. The model is returned to permit
     * cascading. If the listener is not attached to the model, then nothing happens.
     *
     * @return this model, for cascading
     * @see ModelChangedListener
    '''
    # param ModelChangedListener listener
    # result Model
    # @abstractmethod
    # def unregister(self, listener):
    #     pass

    '''
     * Notify any listeners that the event e has occurred.
     *
     * @param e the event that has occurred
    '''
    # param Object e
    # result Model
    # @abstractmethod
    # def notifyEvent(self, e):
    #     pass

    '''
     * Remove all the statements from this model.
    '''
    # param 
    # result Model
    @abstractmethod
    def removeAll(self):
        pass

    '''
     * Remove all the statements matching (s, p, o) from this model.
    '''
    # param Resource s, Property p, RDFNode r
    # result Model
    # @abstractmethod
    # def removeAll(self, s, p, r):
    #     pass

    '''
     * Answer true iff .close() has been called on this Model.
    '''
    # param 
    # result boolean
    @abstractmethod
    def isClosed(self):
        pass

    # Override return type for methods inherited from PrefixMapping
    #@Override
    # param String prefix, String uri
    # result Model
    @abstractmethod
    def setNsPrefix(self, prefix, uri):
        pass

    #@Override
    # param String prefix
    # result Model
    @abstractmethod
    def removeNsPrefix(self, prefix):
        pass

    #@Override
    # param 
    # result Model
    @abstractmethod
    def clearNsPrefixMap(self):
        pass

    #@Override
    # param PrefixMapping other
    # result Model
    @abstractmethod
    def setNsPrefixes(self, other):
        pass

    #@Override
    # param Map<String, String> map
    # result Model
    # @abstractmethod
    # def setNsPrefixes(self, map):
    #     pass

    #@Override
    # param PrefixMapping map
    # result Model
    @abstractmethod
    def withDefaultMappings(self, map):
        pass

